﻿Public Class MobileHDCurveForm

    Private _g As Graphics
    Private _gPrint As Graphics

    Private _bmp As Bitmap
    Private _bmpPrint As Bitmap

    Private _bgColor As Color = Color.Black
    Private _bgColor4Print As Color = Color.White

    Private _foreColor As Color = Color.White
    Private _foreColor4Print As Color = Color.Black

    Private _scaleColor As Color = Color.Gray

    Private _l As New List(Of RTDValueInfo)
    Private _dl As New List(Of RTData)

    Private Const SCALECOUNT As Integer = 5

    Dim aWidth As Integer = 830 '880
    Dim aHeight As Integer = 500
    Dim aTop As Integer = 20
    Dim aLeft As Integer = 180 '120

    Dim _forePen As New Pen(Color.White)
    Dim _forePen4Print As New Pen(Color.Black)

    Private _foreBrush As New SolidBrush(Color.White)
    Private _foreBrush4Print As New SolidBrush(Color.Black)

    '温湿度上下限
    Private Const MAX_TEMP_LIMIT As Integer = 50
    Private Const MIN_TEMP_LIMIT As Integer = 0
    Private Const MAX_HUM_LIMIT As Integer = 100
    Private Const MIN_HUM_LIMIT As Integer = 0



    Private Sub InitBitmap()
        _bmp = New Bitmap(1024, 570, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
        Me.PictureBox1.Image = _bmp
        _g = Graphics.FromImage(_bmp)
        _g.Clear(Color.Black)

        _bmpPrint = New Bitmap(1024, 570, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
        _gPrint = Graphics.FromImage(_bmpPrint)
        _gPrint.Clear(Color.White)
    End Sub

    Private Sub HDCurveForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.cboWarehouse.SelectedIndex = 0
        InitBitmap()
        'LoadWareHouse()
        'Me.WindowState = FormWindowState.Maximized

        'Me.btnRefresh.PerformClick()
    End Sub

    ''' <summary>
    ''' 加载仓库
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub LoadWareHouse()
        Dim rts As RefTypeService = New RefTypeService(MainForm.pi)

        For Each rti As RefTypeItem In rts.GeRefGroupList()
            cboWarehouse.Items.Add(rti)
        Next

        If cboWarehouse.Items.Count >= 1 Then
            cboWarehouse.SelectedIndex = 0
            btnRefresh.Enabled = True
            btnSavePic.Enabled = True
        Else
            cboWarehouse.SelectedIndex = -1
            btnRefresh.Enabled = False
            btnSavePic.Enabled = False
        End If

    End Sub

    Private Sub cboWarehouse_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboWarehouse.SelectedIndexChanged
       
    End Sub

    Private Function CreateRTDValueInfo(ByVal id As Integer, ByVal name As String, ByVal maxvalue As Integer, ByVal minvalue As Integer, ByVal c As Color) As RTDValueInfo
        Dim vi As New RTDValueInfo()
        vi.ID = id
        vi.Name = name
        vi.maxValue = maxvalue
        vi.minValue = minvalue
        vi.color = c
        vi.length = 2
        Return vi
    End Function

    'Private Function CreateRTDValueInfo(ByVal i As Integer) As RTDValueInfo
    '    Return CreateRTDValueInfo(i, Color.Red)
    'End Function

    'Private Function CreateRTDValueInfo(ByVal i As Integer, ByVal c As Color) As RTDValueInfo
    '    Dim strName As String = ""
    '    If i <= 16 Then
    '        If i <= 8 Then
    '            strName = "T" & i.ToString()
    '        Else
    '            strName = "H" & (i - 8).ToString()
    '        End If

    '        'If i Mod 2 = 1 Then
    '        '    strName = "温度" & ((i - 1) \ 2 + 1).ToString()
    '        'Else
    '        '    strName = "湿度" & ((i - 1) \ 2 + 1).ToString()
    '        'End If

    '    ElseIf i <= 25 Then
    '        strName = "TBCC_T" & (i - 16).ToString()

    '    ElseIf i <= 28 Then
    '        strName = "TBCC_H" & (i - 25).ToString()
    '    End If
    '    Return CreateRTDValueInfo(strName, 100, 0, c)
    'End Function

    'Private Function CreateRTDValueInfo(ByVal i As Integer, ByVal maxvalue As Integer, ByVal minvalue As Integer, ByVal c As Color) As RTDValueInfo
    '    Dim strName As String = ""
    '    If i <= 16 Then
    '        If i <= 8 Then
    '            strName = "T" & i.ToString()
    '        Else
    '            strName = "H" & (i - 8).ToString()
    '        End If
    '        'If i Mod 2 = 0 Then
    '        '    strName = "温度" & ((i - 1) \ 2 + 1).ToString()
    '        'Else
    '        '    strName = "湿度" & ((i - 1) \ 2 + 1).ToString()
    '        'End If
    '    ElseIf i <= 25 Then
    '        strName = "TBCC_T" & (i - 16).ToString()

    '    ElseIf i <= 28 Then
    '        strName = "TBCC_H" & (i - 25).ToString()
    '    End If


    '    Return CreateRTDValueInfo(i, strName, maxvalue, minvalue, c)

    'End Function

    Private Sub btnRefresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefresh.Click
        InitBG(_g) '刷新图层但不显示数据

        'RefreshData()
        Me.pnlSearch.Visible = True
        Me.btnRefresh.Enabled = False
        Me.cboWarehouse.Enabled = False
        Me.dtpFrom.Enabled = False
        Me.btnSavePic.Enabled = False
        bwSearch.RunWorkerAsync(New Object() {cboWarehouse.SelectedItem, dtpFrom.Value})
        'RefreshImage()
    End Sub

    ''' <summary>
    ''' 刷新
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub RefreshData(ByVal argument As Object)
        _dl.Clear()

        Dim strSql As String
        Dim cbo_rti As RefTypeItem = argument(0) 'CType(cboWarehouse.SelectedItem, RefTypeItem)

        strSql = String.Format("Select * From tbccHDData_{0}_{1} where hDate like '{2}%00' Order by hdate", cbo_rti.ProjectID.Replace("-", "_"), cbo_rti.NetId, CType(argument(1), Date).ToString("yyyy-MM-dd"))

        Dim ds As DataSet
        ds = SqlHelper.ExecuteDataset(strSql, Nothing)

        Dim count As Integer
        count = ds.Tables(0).Rows.Count

        Dim dt As DateTime

        For Each vi As RTDValueInfo In _l
            Dim v(24 * 60) As Single
            For j As Integer = 0 To v.Length - 1
                v(j) = Single.NaN
            Next

            Dim proIndex As Integer = 0
            Dim i As Integer = 0
            For Each r As DataRow In ds.Tables(0).Rows
                If Me.bwSearch.CancellationPending Then '取消查询
                    ds.Clear() : ds.Dispose() : ds = Nothing
                    Exit Sub
                End If
                dt = r("hDate")
                'If dt.Second <> 0 Then '非整分钟
                '    Continue For
                'End If

                i = dt.Minute + dt.Hour * 60

                If i Mod 2 = 1 Then
                    Continue For
                End If

                i = i / 2

                v(i) = r(String.Format("AI{0}", vi.ID.ToString()))
                proIndex += 1
                ReportProgress((proIndex / ds.Tables(0).Rows.Count) * 100) '进度报告
            Next

            Dim item As New RTData()
            item._bufSingle = v
            item.rtdItem = vi

            _dl.Add(item)
        Next


        'For Each vi As RTDValueInfo In _l

        '    Dim v(86400 / 120) As Single
        '    For i As Integer = 0 To v.Length - 1
        '        v(i) = g_rand.Next(30, 70)
        '    Next

        '    Dim item As New RTData()
        '    item._bufSingle = v
        '    item.rtdItem = vi

        '    _dl.Add(item)
        'Next

    End Sub


    Private Sub RefreshImage()
        'InitBG(_g)
        DrawLine(_g)
        Me.PictureBox1.Image = _bmp
    End Sub

    Private Sub RefreshImage4Print()
        InitBG4Print(_gPrint)
        DrawLine4Print(_gPrint)
        'Me.PictureBox1.Image = _bmpPrint
    End Sub

    ''' <summary>
    ''' 初始化背景
    ''' </summary>
    ''' <param name="g"></param>
    ''' <remarks></remarks>
    Private Sub InitBG(ByVal g As Graphics)
        g.Clear(_bgColor)
        DrawMark(g)
        DrawCoordinates(g)
        DrawXCoordinate(g)
        DrawYCoordinate(g)
    End Sub



    Private Sub DrawMark(ByVal g As Graphics)
        Dim markTop As Integer = 25
        Dim height As Integer = 20

        Dim iRow As Integer = 0
        For Each item As RTDValueInfo In _l
            Dim r As New Rectangle(aLeft + aWidth - 100, iRow * height + markTop + 1, 10, 10)
            Dim b As Brush = New SolidBrush(item.color)
            g.FillRectangle(b, r)
            Dim s As String
            s = item.Name
            g.DrawString(s, Me.Font, _foreBrush, aLeft + aWidth - 80, iRow * height + markTop)
            iRow += 1
        Next
    End Sub

    Private Sub DrawCoordinates(ByVal g As Graphics)
        Dim r As New Rectangle(aLeft, aTop, aWidth, aHeight)
        g.DrawRectangle(_forePen, r)
        'g.DrawLine(_forePen, aLeft, aTop + aHeight \ 2, aLeft + aWidth, aTop + aHeight \ 2)
    End Sub

    Private Sub DrawXCoordinate(ByVal g As Graphics)
        'If Me._dl.Count = 0 Then
        '    Exit Sub
        'End If

        'Dim index As Integer
        'index = Me._dl(0).CurrentIndex

        Dim dt As DateTime
        dt = Me.GetCurrentTime

        Dim p As New Pen(Brushes.Gray, 2)

        Dim sTime As String

        For i As Integer = 0 To 24
            sTime = i.ToString.PadLeft(2, "0")
            g.DrawString(sTime, Me.Font, _foreBrush, GetX(i * 30) - 8, aTop + aHeight + 5)
            p.Width = 1
            g.DrawLine(p, GetX(i * 30), aTop, GetX(i * 30), aTop + aHeight)
        Next

        p.Dispose()

    End Sub

    Private Sub DrawYCoordinate(ByVal g As Graphics)
        Dim gap As Integer = 15

        Dim x As Integer = aLeft
        Dim iRow As Integer = 0
        Dim index As Integer = 0
        For Each item As RTDValueInfo In _l
            If item.length <= 1 Then
                Continue For
            End If

            index += 1

            x -= gap
            Dim p As New Pen(item.color)

            Dim yd As Integer = 0

            g.DrawLine(p, x, aTop + yd, x, aTop + aHeight + yd)

            g.DrawLine(p, x, aTop + yd, x + gap, aTop + yd)
            g.DrawLine(p, x, aTop + aHeight + yd, x + gap, aTop + aHeight + yd)

            If index Mod 2 = 0 Then
                yd = -12
            End If

            Dim kd As Integer = aHeight / SCALECOUNT
            Dim b As New SolidBrush(item.color)
            Dim s As String
            For k As Integer = 0 To SCALECOUNT
                s = item.maxValue - k * (item.maxValue - item.minValue) / SCALECOUNT
                g.DrawString(s, Me.Font, b, x, aTop + k * kd + yd)
                g.DrawLine(p, x - 2, aTop + k * kd, x + 2, aTop + k * kd)
            Next

            p.Dispose()
            b.Dispose()

            'x += gap
        Next

        Dim y As Integer = 0
        For i As Integer = 1 To SCALECOUNT - 1
            y += Me.aHeight / SCALECOUNT
            'g.DrawLine(Me._forePen, aLeft, aTop + y, aLeft + aWidth, aTop + y)
            g.DrawLine(Pens.Gray, x, aTop + y, aLeft + aWidth, aTop + y)
        Next
    End Sub

    Private Function GetX(ByVal x As Integer) As Integer
        Return Me.aLeft + x
    End Function

    'Public Function GetY3(ByVal y As Single, ByVal r As RTDValueInfo) As Integer
    '    Dim rn As New Random
    '    'y = rn.Next(1, 120)
    '    Dim t As Integer
    '    t = aHeight + aTop - ((y - r.minValue) / (r.maxValue - r.minValue)) * aHeight '- (r.maxValue + r.minValue) / 2
    '    Return t
    '    'Return 10 + y / 20
    'End Function

    Public Function GetY(ByVal y As Single, ByVal r As RTDValueInfo) As Integer
        Dim rn As New Random
        'y = rn.Next(1, 120)

        Dim t As Integer

        'todo:y值无效
        y = y Mod 20000

        Try
            t = aHeight + aTop - ((y - r.minValue) / (r.maxValue - r.minValue)) * aHeight '- (r.maxValue + r.minValue) / 2
        Catch ex As Exception
            Debug.WriteLine(ex.ToString)
            Throw ex
        End Try


        'Debug.WriteLine(r.Name & ": " & y & " - " & t)
        Return t
        'Return 10 + y / 20
    End Function


    Public Function GetY(ByVal y As Single) As Integer
        Return 10 + y / 20
    End Function

    Private Function GetCurrentTime() As DateTime
        Return dtpTo.Value
    End Function

    Private Sub DrawLine(ByVal g As Graphics)
        Dim SwitchCount As Integer = 0

        For Each d As RTData In _dl

            If d.rtdItem.length = 0 Then
                '开关量
                SwitchCount += 1
                Dim yy As Integer = Me.aTop + Me.aHeight - SwitchCount * 12

                Dim p As New Pen(d.rtdItem.color, 10)
                Dim p2 As New Pen(d.rtdItem.color, 1)
                For i As Integer = 1 To d.CurrentIndex
                    If d._bufByte(i) Mod 2 = 0 Then
                        g.DrawLine(p2, GetX(i - 1), yy, GetX(i), yy)
                    Else
                        g.DrawLine(p, GetX(i - 1), yy, GetX(i), yy)
                    End If
                Next
                p.Dispose()
                p2.Dispose()

            Else
                '曲线

                Dim p As New Pen(d.rtdItem.color)
                For i As Integer = 1 To d._bufSingle.Length - 1
                    If Not (Single.IsNaN(d._bufSingle(i - 1)) OrElse Single.IsNaN(d._bufSingle(i))) Then
                        _g.DrawLine(p, GetX(i - 1), GetY(d._bufSingle(i - 1), d.rtdItem), GetX(i), GetY(d._bufSingle(i), d.rtdItem))
                    End If
                Next
                p.Dispose()
            End If
        Next
    End Sub


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'If 1 = 1 Then
        '    Exit Sub
        'End If

        'Dim strSql As String

        'strSql = "Delete From tbccHDData"
        'SqlHelper.ExecuteNonQuery(strSql, Nothing)

        'Dim dt As DateTime = Now.ToLongDateString()

        'Dim tic As New TBCC.Utility.TranstrationItem()

        'For i As Integer = 0 To 2000
        '    strSql = "Insert Into tbccHDData(hdate,AI1,AI2,AI3,AI4,AI5,AI6,AI7,AI8,AI9,AI10,AI11,AI12,AI13,AI14,AI15,AI16,DO1,DO2,DO3,DO4,DO5,DO6) Values(?,?,?,?,?,  ?,?,?,?,?,  ?,?,?,?,?,  ?,?,1,1,1,  0,0,1) --" & i.ToString()

        '    Dim p(16) As SQLite.SQLiteParameter
        '    For j As Integer = 0 To p.Length - 1
        '        p(j) = New SQLite.SQLiteParameter()
        '    Next

        '    p(0).Value = UtilityClass.GetDateString(dt.AddMinutes(i * 2))

        '    For k As Integer = 1 To 16
        '        p(k).Value = g_rand.Next(20 - k, 50 + k * 2)
        '    Next

        '    tic.Add(strSql, p)
        'Next

        'SqlHelper.ExecuteTranstration(tic)


    End Sub

    Private Sub dtpFrom_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpFrom.ValueChanged

    End Sub


    Private Sub btnSavePic_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSavePic.Click
        Dim dlg As New SaveFileDialog
        dlg.FileName = Now.ToString("yyyyMMdd") & ".bmp"
        If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
            RefreshImage4Print()
            Me._bmpPrint.Save(dlg.FileName, System.Drawing.Imaging.ImageFormat.Bmp)
            'Me.PictureBox1.Image.Save(dlg.FileName, System.Drawing.Imaging.ImageFormat.Bmp)
        End If
    End Sub


#Region ""

    Private Sub InitBG4Print(ByVal g As Graphics)
        g.Clear(Color.White)
        DrawMark4Print(g)
        DrawCoordinates4Print(g)
        DrawXCoordinate(g)
        DrawYCoordinate(g)
    End Sub

    ''' <summary>
    ''' 画曲线(打印用)
    ''' </summary>
    ''' <param name="g"></param>
    ''' <remarks></remarks>
    Private Sub DrawLine4Print(ByVal g As Graphics)
        Dim SwitchCount As Integer = 0
        For Each d As RTData In _dl
            If d.rtdItem.length = 0 Then
                '开关量
                SwitchCount += 1
                Dim yy As Integer = Me.aTop + Me.aHeight - SwitchCount * 12

                Dim p As New Pen(d.rtdItem.color, 10)
                Dim p2 As New Pen(d.rtdItem.color, 1)
                For i As Integer = 1 To d.CurrentIndex
                    If d._bufByte(i) Mod 2 = 0 Then
                        g.DrawLine(p2, GetX(i - 1), yy, GetX(i), yy)
                    Else
                        g.DrawLine(p, GetX(i - 1), yy, GetX(i), yy)
                    End If
                Next
                p.Dispose()
                p2.Dispose()

            Else
                '曲线

                Dim p As New Pen(d.rtdItem.color)
                For i As Integer = 1 To d._bufSingle.Length - 1
                    'CurrentIndex=0 ??????
                    If Not (Single.IsNaN(d._bufSingle(i - 1)) OrElse Single.IsNaN(d._bufSingle(i))) Then
                        g.DrawLine(p, GetX(i - 1), GetY(d._bufSingle(i - 1), d.rtdItem), GetX(i), GetY(d._bufSingle(i), d.rtdItem))
                    End If
                Next
                p.Dispose()
            End If
        Next
    End Sub

    Private Sub DrawCoordinates4Print(ByVal g As Graphics)
        Dim r As New Rectangle(aLeft, aTop, aWidth, aHeight)
        g.DrawRectangle(_forePen4Print, r)
    End Sub

    Private Sub DrawMark4Print(ByVal g As Graphics)
        Dim markTop As Integer = 25
        Dim height As Integer = 20

        Dim iRow As Integer = 0
        For Each item As RTDValueInfo In _l
            Dim r As New Rectangle(860, iRow * height + markTop + 1, 10, 10)
            Dim b As Brush = New SolidBrush(item.color)
            g.FillRectangle(b, r)
            Dim s As String
            s = item.Name
            g.DrawString(s, Me.Font, _foreBrush4Print, 880, iRow * height + markTop)
            iRow += 1
        Next

    End Sub
#End Region

    Private Delegate Sub VoidMethodHandler(ByVal obj As Object)
    Private Sub bwSearch_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwSearch.DoWork
        Dim obj As Object = Nothing

        Dim str As String = String.Format("正在生成{0}历史曲线……", e.Argument(0))
        If Me.InvokeRequired Then
            Me.Invoke(New VoidMethodHandler(AddressOf SetSearchState), str)
        Else
            SetSearchState(str)
        End If

        RefreshData(e.Argument)

        If Me.InvokeRequired Then
            Me.Invoke(New VoidMethodHandler(AddressOf RefreshImageMethod), obj)
        Else
            RefreshImage()
        End If

    End Sub

    Private Sub bwSearch_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwSearch.ProgressChanged
        Me.pbSearch.Value = e.ProgressPercentage
    End Sub

    Private Sub bwSearch_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwSearch.RunWorkerCompleted
        Me.cboWarehouse.Enabled = True
        Me.dtpFrom.Enabled = True
        Me.btnSavePic.Enabled = True
        Me.btnRefresh.Enabled = True
        Me.pnlSearch.Visible = False

        GC.Collect()
    End Sub
    Private Sub RefreshImageMethod(ByVal obj As Object)
        RefreshImage()
    End Sub
    Private Sub ReportProgress(ByVal value As Integer)
        If Not Me.IsDisposed Then
            If Me.InvokeRequired Then
                Me.Invoke(New VoidMethodHandler(AddressOf ReportProgressMethod), value)
            Else
                ReportProgressMethod(value)
            End If
        End If
    End Sub
    Private Sub ReportProgressMethod(ByVal obj As Object)
        Me.bwSearch.ReportProgress(obj)
    End Sub
    Private Sub SetSearchState(ByVal obj As Object)
        Me.lblSearchState.Text = obj
    End Sub
End Class